#ifndef __JC_H__
#define __JC_H__

#ifdef JC_EXPORTS
#define JC_CLASS	__declspec(dllexport)
#else
#define JC_CLASS	__declspec(dllimport)
#endif


///////////////////////////////////////////////////////////////////////////////
//class JException
class JC_CLASS JException
{
public:
	JException(const wchar_t *file, const wchar_t *func, int line, const wchar_t *message, ...);
	JException(const wchar_t *file, const wchar_t *func, int line, unsigned long code, const wchar_t *message, ...);
	virtual ~JException(void);

public:
	const wchar_t *m_file;
	const wchar_t *m_func;
	int m_line;
	wchar_t *m_message;
};

#ifndef WIDEN2
#define WIDEN2(x) L ## x
#endif
#ifndef WIDEN
#define WIDEN(x) WIDEN2(x)
#endif
#ifndef __WFILE__
#define __WFILE__ WIDEN(__FILE__)
#endif
#ifndef __WFUNCSIG__
#define __WFUNCSIG__  WIDEN(__FUNCSIG__)
#endif
#define THROW_JEXCEPTION(message, ...)		throw JException(__WFILE__, __WFUNCSIG__, __LINE__, message, __VA_ARGS__)
#define THROW_JEXCEPTION_WIN(r, message, ...)		throw JException(__WFILE__, __WFUNCSIG__, __LINE__, r, message, __VA_ARGS__)

 
#include "JHashMap.h"
///////////////////////////////////////////////////////////////////////////////
//logger
//class JC_CLASS JLogger
//{
//	JLogger(void);
//	JLogger(const JLogger&);
//	JLogger& operator=(const JLogger&);
//public:
//	typedef enum LOG_LEVEL
//	{
//		LOG_LEVEL_DEBUG = 1,
//		LOG_LEVEL_INFO,
//		LOG_LEVEL_WARN,
//		LOG_LEVEL_ERROR
//	}LOG_LEVEL;
//public:
//	static JLogger& getRoot(void);
//	JLogger getLogger(const wchar_t *category);
//
//	void log(LOG_LEVEL level, const wchar_t *file, const wchar_t *func, int line, const wchar_t *message, ...);
//
//public:
//	LOG_LEVEL m_logLevel;
//};
//
//#define logError(logger, message, ...)			do{if(logger.m_logLevel <= JLogger.LOG_LEVEL_ERROR) logger.log(JLogger.LOG_LEVEL_ERROR, __WFILE__, __WFUNCSIG__, __LINE__, message, __VA_ARGS__)}while(0)
//#define logWarn(logger, message, ...)			do{if(logger.m_logLevel <= JLogger.LOG_LEVEL_WARN) logger.log(JLogger.LOG_LEVEL_WARN, __WFILE__, __WFUNCSIG__, __LINE__, message, __VA_ARGS__)}while(0)
//#define logInfo(logger, message, ...)			do{if(logger.m_logLevel <= JLogger.LOG_LEVEL_INFO) logger.log(JLogger.LOG_LEVEL_INFO, __WFILE__, __WFUNCSIG__, __LINE__, message, __VA_ARGS__)}while(0)
//#define logDebug(logger, message, ...)			do{if(logger.m_logLevel <= JLogger.LOG_LEVEL_DEBUG) logger.log(JLogger.LOG_LEVEL_DEBUG, __WFILE__, __WFUNCSIG__, __LINE__, message, __VA_ARGS__)}while(0)

///////////////////////////////////////////////////////////////////////////////
//class JStream
class JC_CLASS JStream
{
	JStream(const JStream&);
	JStream& operator=(const JStream&);
public:
	JStream(void);
	virtual ~JStream(void);

	void ensure(size_t len);
	void setLength(size_t len);
	void clear(void);

	unsigned char *getData(void)const{return m_data;}
	size_t getCapacity(void)const{return m_capacity;}

	void write(const void *data, size_t len);

#if _DEBUG
	static void Test(void);
#endif

private:
	unsigned char *m_data;
	size_t	m_capacity;
	size_t m_length;
	size_t m_position;
};

///////////////////////////////////////////////////////////////////////////////
//class JString
class JC_CLASS JString
{
	JString(const JString&);
	JString& operator=(const JString&);

public:
	JString(void);
	virtual ~JString(void);

	operator const wchar_t*(void);

	void JString::format(const wchar_t *fmt, ...);;
	void JString::formatV(const wchar_t *fmt, va_list args);

	BOOL getEnvironmentVariable(const wchar_t *varname);
#if _DEBUG
	static void Test(void);
#endif
private:
	JStream m_data;
};




#endif
